package com.css.sword.knowing.search;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.client.transport.TransportClient.Builder;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;

import com.css.sword.knowing.search.exception.ArgException;
import com.css.sword.knowing.search.tool.MappingTool;
import com.css.sword.knowing.search.util.ToJson;

/**
 * @author 作者 E-mail:caihx@css.com.cn
 * @date 创建时间：2018年1月2日 下午3:42:19
 * @version 1.0
 */
public class SearcherIndex {

	private TransportClient client = null;
	private List<String> addressList;
	private String clusterName;

	public SearcherIndex(String clusterName, String address) {
		this.clusterName = clusterName;
		this.addressList = new ArrayList<String>();
		this.addressList.add(address);

		getClient();
	}

	public SearcherIndex(String clusterName, String[] addressList) {
		this.clusterName = clusterName;

		List<String> list = Arrays.asList(addressList);
		this.addressList = new ArrayList<String>(list);

		getClient();
	}

	/**
	 * 获取搜索服务器的链接
	 * 
	 */
	private void getClient() {
		Builder builder = TransportClient.builder();

		Settings.Builder settingsBuilder = Settings.settingsBuilder();

		Settings settings = settingsBuilder.put("cluster.name", clusterName)
				.put("client.transport.sniff", true).build();
				
		client = builder.settings(settingsBuilder.build()).build();

		for (String str : addressList) {
			String[] arr = str.split(":");

			int port = 9300;
			String ip = "localhost";
			if (arr.length == 2)
				port = Integer.parseInt(arr[1]);
			if (arr.length > 0)
				ip = arr[0];
			try {
				client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(ip), port));
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * 类被破坏时，释放链接
	 * 
	 */
	@Override
	protected void finalize() throws Throwable {
		release();
	}

	/**
	 * 释放已获取的服务器链接句柄，同时连接池也一并释放。单次测试时可以调用此接口； 正式对外的检索服务不要调用。
	 */
	public void release() {
		if (client != null)
			client.close();
		client = null;
	}

	/**
	 * 创建索引
	 * 
	 * @param ii
	 *            创建索引输入 ，详见IndexInput类
	 * @return 如果完全创建成功，返回null，否则返回错误消息
	 * @throws IOException
	 * @throws ArgException
	 */
	public String createIndex(IndexInput ii) throws IOException {

		String errMsg = "";

		if (client != null) {
			IndexRequestBuilder irb = client.prepareIndex(ii.getIndexName(), ii.getTypeName());// .setRefresh(true);
			BulkRequestBuilder bulkRequest = client.prepareBulk();

			for (int i = 0; i < ii.getIndexDocs().size(); i++) {
				XContentBuilder sourceBuilder = ToJson.getJsonBuilder(ii.getIndexDocs().get(i).getData(),
						ii.getSystemID());
				irb = client.prepareIndex(ii.getIndexName(), ii.getTypeName());// .setRefresh(true);
				irb.setSource(sourceBuilder);

				String key = ii.getIndexDocs().get(i).getKey();
				if (null != key && !key.isEmpty()) {
					irb.setId(key);
				}

				String routing = ii.getIndexDocs().get(i).getRouting();
				if (null != routing && !routing.isEmpty()) {
					irb.setRouting(routing);
				}

				bulkRequest.add(irb);
				// bulkRequest.add(client.prepareIndex(ii.getIndexName(),
				// ii.getType()).setRefresh(true).setSource(ii.getData()));
			}
			bulkRequest.setRefresh(true);
			BulkResponse bulkResponse = bulkRequest.execute().actionGet();
			if (bulkResponse.hasFailures()) {
				// errMsg = bulkResponse.buildFailureMessage();
				for (BulkItemResponse brps : bulkResponse.getItems()) {
					if (null != brps.getFailure()) {
						errMsg += brps.getIndex();
						errMsg += ", ";
						errMsg += brps.getType();
						errMsg += ", ";
						errMsg += brps.getId();
						errMsg += ", ";
						errMsg += brps.getFailureMessage();
						errMsg += "\n";
					}
				}
			}
		} else {
			errMsg = "未连接索引服务器";
		}
		return errMsg;
	}

	/**
	 * @param indexName
	 *            索引名称
	 * @param typeName
	 *            索引类型
	 * @param mapping
	 *            mapping结构
	 * @param settings
	 *            索引属性
	 * @return true：创建成功，false：创建失败
	 */
	public boolean createMapping(String indexName, String typeName, Map<String, Object> mapping,
			Map<String, Object> settings) {
		return MappingTool.create(client, indexName, typeName, mapping, settings);
	}
}
